/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/cat.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../msg_aio/head.h"
#include "../macro/head.h"
#include "../impl/head.h"
#include "../msg/head.h"
#include "../impl/head.h"
#include "helper_package.h"
#include "encrypt_tcp.h"

namespace cat
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 

	encrypt_tcp::encrypt_tcp()
	{
	}

	encrypt_tcp::~encrypt_tcp()
	{
	}

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// proc

	int encrypt_tcp::proc( xos::i_msg *& pMsg )
	{
        int ret = 1;

        int nMsg = pMsg->get_int( 0, 0 );

        switch( nMsg )
        {
        case PACKET_TCP_UN_ENCRYPT_FLUSH:
            {
                flush( pMsg );
            }
            break;
        case PACKET_TCP_UN_ENCRYPT:
            {
                un_encrypt( pMsg );
            }
            break;
        case PACKET_TCP_ENCRYPT:
            {
                encrypt( pMsg );
            }
            break;
        default:
            {
                ret = 0;
            }
            break;
        }

        return ret;
	}

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int encrypt_tcp::helper_un_encrypt( xos::i_msg *& pMsg )
    {
        int ret = 0;

        task * pTask = ( task * )pMsg->get_void( 0, 0 );
        request * pRequest = pTask->m_pRequest;

        pRequest->m_pUnEnctyptList->add_to_tail( pRequest->m_pRecvList );
        pMsg->set_void( 0, pTask );
        msg::notify_package( pMsg, PACKET_TCP_UN_PACKAGE, false );
        pTask = 0;

        return ret;
    }

    int encrypt_tcp::un_encrypt( xos::i_msg *& pMsg )
    {
        int ret = 0;

        task * pTask = ( task * )pMsg->get_void( 0, 0 );
        connection * pConnect = pTask->m_pConnection;
        request * pRequest = pTask->m_pRequest;
        xos::i_buf * pBuf = pMsg->get_buf( 0, 0 );

        {
            pRequest->m_pRecvList->push_back( pBuf );
            pTask->lock_server_for_request_data();
            pConnect->un_lock_server();
            pBuf = 0;
        }

        if( !pConnect->ssl() )
        {
            pRequest->m_pUnEnctyptList->add_to_tail( pRequest->m_pRecvList );
            pMsg->set_void( 0, pTask );
            msg::notify_package( pMsg, PACKET_TCP_UN_PACKAGE, false );
        }
        else
        {
            ret = helper_un_encrypt( pMsg );
        }

        pTask->un_lock_server_for_request_data();

        if( ( ret < 0 ) && pConnect->running() )
        {
            pConnect->set_data_err();
            pConnect->lock_server();
            pMsg->set_void( 0, pConnect );
            pMsg->set_int( 0, NET_TCP_DATA_ERR );
            msg::notify_net( pMsg, false );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int encrypt_tcp::helper_encrypt( xos::i_msg *& pMsg )
    {
        int ret = 0;

        task * pTask = ( task * )pMsg->get_void( 0, 0 );
        response * pResponse = pTask->m_pResponse;

        pResponse->m_pEnctyptList->add_to_tail( pResponse->m_pPackageList );

        return ret;
    }

    int encrypt_tcp::encrypt( xos::i_msg *& pMsg )
    {
        int ret = 0;

        task * pTask = ( task * )pMsg->get_void( 0, 0 );
        connection * pConnect = pTask->m_pConnection;
        response * pResponse = pTask->m_pResponse;

        if( !pConnect->ssl() )
        {
            pResponse->m_pEnctyptList->add_to_tail( pResponse->m_pPackageList );
        }
        else
        {
            ret = helper_encrypt( pMsg );
        }

        if( 0 == ret )
        {
            aio_tcp obj;
            obj.post_send( pConnect, pResponse->m_pEnctyptList );
        }

        if( ( ret < 0 ) && pConnect->running() )
        {
            pConnect->set_data_err();
            pConnect->lock_server();
            pMsg->set_void( 0, pConnect );
            pMsg->set_int( 0, NET_TCP_DATA_ERR );
            msg::notify_net( pMsg, false );
        }

        task::term_task( pTask );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int encrypt_tcp::flush( xos::i_msg *& pMsg )
    {
        int ret = 0;

        msg::notify_package( pMsg, PACKET_TCP_UN_PACKAGE_FLUSH, false );

        return ret;
    }

} // cat
